package cn.jesin.css.utils;

import cn.hutool.core.io.FileUtil;
import cn.jesin.css.vo.FileInfo;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.URL;
import java.util.Date;

/**
 * @author 谷汉斌
 * @description
 * @createTime 2024/8/22 上午11:34
 */
@Component
public class OSSFileUtil {

    @Value("${aliyunInfo.endpoint}")
    private String endPoint;
    @Value("${aliyunInfo.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyunInfo.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyunInfo.bucketName}")
    private String bucketName;

    /**
     * 上传文件到OSS，并返回文件的访问路径
     *
     * @param file 文件
     * @return url 访问路径
     */
    public FileInfo uploadToOss(MultipartFile file) {
        // 判断文件是否为空
        if (file == null) {
            return null;
        }
        // 获取文件名
        String objectName = file.getOriginalFilename();
        // 获取文件后缀
        String suffix = FileUtil.extName(objectName);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        try {
            // 获取文件输入流
            InputStream inputStream = file.getInputStream();
            //设置上传的文件名
            objectName = System.currentTimeMillis() + objectName;
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            //设置上传文件的元信息
            ObjectMetadata metadata = new ObjectMetadata();
            //文件类型
            if ("jpg".equals(suffix) || "png".equals(suffix) || "jpeg".equals(suffix)) {
                metadata.setContentType("image/" + suffix);
            } else if ("mp4".equals(suffix)) {
                metadata.setContentType("video/" + suffix);
            }
            putObjectRequest.setMetadata(metadata);
            //上传文件
            ossClient.putObject(putObjectRequest);
            // 指定生成的签名URL过期时间，单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000L);
            // 生成签名URL
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
            // 设置过期时间。
            request.setExpiration(expiration);
            // 通过HTTP GET请求生成签名URL。
            URL signedUrl = ossClient.generatePresignedUrl(request);
            // 返回文件名和签名URL。
            return new FileInfo(objectName, signedUrl.toString());
        } catch (Exception e) {
            throw new RuntimeException("上传文件失败", e);
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * 删除文件
     */
    public void deleteFile(String fileName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        try {
            // 删除文件。
            ossClient.deleteObject(bucketName, fileName);
        } catch (Exception e) {
            throw new RuntimeException("删除文件失败", e);
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * 获取文件的URL
     */
    public String getUrl(String fileName) {
        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        try {
            // 生成签名URL。
            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000L);
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, fileName, HttpMethod.GET);
            // 设置过期时间。
            request.setExpiration(expiration);
            // 通过HTTP GET请求生成签名URL。
            URL signedUrl = ossClient.generatePresignedUrl(request);
            return signedUrl.toString();
        } catch (Exception e) {
            throw new RuntimeException("获取文件URL失败", e);
        } finally {
            ossClient.shutdown();
        }
    }
}
